﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using SocketCore;
using SocketCore.Network;
using System.Threading;

namespace SocketServerTest
{
    public partial class Form1 : Form
    {
        private SocketServer m_sockServer = new SocketServer();
        private DummyMessageHandler dumpMsgHandler = null;
        private bool m_bStarted = false;
        private IList<IoSession> lsSessions = new List<IoSession>();
        private ReaderWriterLock lockLstSession = new ReaderWriterLock();
        public Form1()
        {
            InitializeComponent();
        }

        void ChangeConnectionState(bool bConnected)
        {
            if(bConnected)
            {
                Log("Started!\r\n");
                m_bStarted = true;
                button1.Text = "Stop";
            }
            else
            {
                Log("Stopped!\r\n");
                m_bStarted = false;
                button1.Text = "Start";
            }
            
            
        }
        private void button1_Click(object sender, EventArgs e)
        {
            if(dumpMsgHandler == null)
            {
                dumpMsgHandler = new DummyMessageHandler(m_sockServer);
                dumpMsgHandler.Connected += new EventHandler(dumpMsgHandler_Connected);
                dumpMsgHandler.Disconnected += new EventHandler(dumpMsgHandler_Disconnected);
                dumpMsgHandler.MessageReceived += new EventHandler(dumpMsgHandler_MessageReceived);
                dumpMsgHandler.MessageSent += new EventHandler(dumpMsgHandler_MessageSent);
                dumpMsgHandler.SocketError += new EventHandler(dumpMsgHandler_SocketError);
                dumpMsgHandler.SocketIdle += new EventHandler(dumpMsgHandler_SocketIdle);
            }

            if(!m_bStarted)
            {
                m_sockServer.Start(dumpMsgHandler);
                ChangeConnectionState(true);
            }
            else
            {
                lockLstSession.AcquireWriterLock(1000);
                foreach(IoSession session in lsSessions)
                {
                    session.Close();
                }
                lsSessions.Clear();
                lockLstSession.ReleaseWriterLock();
                m_sockServer.Stop();
                ChangeConnectionState(false);
            }
        }

        void dumpMsgHandler_SocketIdle(object sender, EventArgs e)
        {
            IoSession session = (IoSession)sender;
            string s = string.Format("Socket idle: {0}\r\n", session.RemoteHost);
            Log(s);
        }

        void dumpMsgHandler_SocketError(object sender, EventArgs e)
        {
            object[] arr = (object[]) sender;
            IoSession session = (IoSession)arr[0];
            Exception ex = (Exception)arr[1];
            string s = string.Format("Socket error on {0}. Error: {1}\r\n", session.RemoteHost, ex.Message);
            Log(s);
            lockLstSession.AcquireWriterLock(1000);
            lsSessions.Remove(session);
            lockLstSession.ReleaseWriterLock();
        }

        void dumpMsgHandler_Disconnected(object sender, EventArgs e)
        {
            IoSession session = (IoSession) sender;
            string s = string.Format("Disconnected: {0}\r\n", session.RemoteHost);
            Log(s);
            lockLstSession.AcquireWriterLock(1000);
            lsSessions.Remove(session);
            lockLstSession.ReleaseWriterLock();
        }

        void dumpMsgHandler_Connected(object sender, EventArgs e)
        {
            IoSession session = (IoSession)sender;
            string s = string.Format("Connected: {0}\r\n", session.RemoteHost);
            Log(s);
            lockLstSession.AcquireWriterLock(1000);
            if (!lsSessions.Contains(session))
                lsSessions.Add(session);
            lockLstSession.ReleaseWriterLock();
        }

        void dumpMsgHandler_MessageReceived(object sender, EventArgs e)
        {
            IoSession session = (IoSession)sender;
            string s = string.Format("Received from: {0}. Replied!\r\n", session.RemoteHost);
            Log(s);
        }

        void dumpMsgHandler_MessageSent(object sender, EventArgs e)
        {
            IoSession session = (IoSession)sender;
            string s = string.Format("Sent to: {0}\r\n", session.RemoteHost);
            Log(s);
        }

        private delegate void LogFunc(string s);
        void Log(string s)
        {
            if(txtLog.InvokeRequired)
                this.Invoke(new LogFunc(Log), s);
            else
                txtLog.Text += s;
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            lockLstSession.AcquireReaderLock(1000);
            m_sockServer.SocketService.Send(lsSessions,
                                            new SocketCore.Network.Message(PackageTypeEnum.Ascii, true, "fucked!"));
            lockLstSession.ReleaseReaderLock();
        }
    }
}
